﻿using PipeSockets;
using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO.Pipelines;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace SimpleSockets
{
    public class TcpServer
    {
        private readonly Socket _socket;
        private readonly EndPoint _endPoint;
        private readonly int _backlog;
        private long _id;
        private IProtocolParser _protocolParser;
        public readonly PipeOptions _sendOptions;
        public readonly PipeOptions _recvOptions;
        private readonly ConcurrentDictionary<long, TcpConnection> _connectionManager;
        public Action<AbstractConnection, ReadOnlySequence<byte>> MessageReceived;

        public TcpServer(EndPoint endPoint, int backlog, IProtocolParser protocolParser)
        {
            _endPoint = endPoint;
            _backlog = backlog;
            _protocolParser = protocolParser;
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _connectionManager = new ConcurrentDictionary<long, TcpConnection>();
        }

        public async Task StartAsync(CancellationToken cancellationToken = default)
        {
            try
            {
                _socket.Bind(_endPoint);
                _socket.Listen(_backlog);
                while (!cancellationToken.IsCancellationRequested)
                {
                    var socket = await _socket.AcceptAsync(cancellationToken);
                    TcpConnection connection = new TcpConnection(socket, _protocolParser, MessageReceived, _sendOptions, _recvOptions);
                    _connectionManager.TryAdd(Interlocked.Increment(ref _id), connection);
                    await connection.StartAsync(cancellationToken);
                }
            }
            catch (Exception ex)
            {
                // 记录异常信息（可选）
            }
        }


        public async Task StopAsync(CancellationToken cancellationToken = default)
        {
            try
            {
                // 停止监听新的连接请求
                _socket.Shutdown(SocketShutdown.Receive); // 阻止接受新的连接
                _socket.Close(); // 关闭监听套接字

                // 关闭现有的连接
                var connectionsToClose = _connectionManager.Values.ToList();
                var closeTasks = new List<Task>();

                foreach (var connection in connectionsToClose)
                {
                    closeTasks.Add(connection.StopAsync(cancellationToken));
                }

                await Task.WhenAll(closeTasks).ConfigureAwait(false); // 等待所有连接关闭完毕

                // 清理和释放资源
                _connectionManager.Clear(); // 清空连接管理器
                _socket.Dispose(); // 释放监听套接字资源
            }
            catch (Exception ex)
            {
                // 记录异常信息（可选）
            }
        }
    }
}
